package com.haixiaoke.saas.repository.util.Tree;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Tree implements Serializable {
    List<Node> nodes;

    public Tree(List<Node> nodes) {
        this.nodes = nodes;
    }

    /**
     * 构建树形结构
     */
    public List<Node> buildTree() {
        List<Node> Nodes = new ArrayList<>();
        List<Node> rootNodes = getRootNodes();
        for (Node rootNode : rootNodes) {
            buildChildNodes(rootNode);
            Nodes.add(rootNode);
        }
        return Nodes;
    }

    /**
     * 递归子节点
     */
    private void buildChildNodes(Node node) {
        List<Node> children = getChildNodes(node);
        if (!children.isEmpty()) {
            for (Node child : children) {
                buildChildNodes(child);
            }
            if (CollUtil.isNotEmpty(children)) {
                node.setChildren(children);
            }
        }
    }

    /**
     * 获取父节点下所有的子节点
     */
    public List<Node> getChildNodes(Node pNode) {
        List<Node> childNodes = new ArrayList<>();
        for (Node n : nodes) {
            if (StrUtil.equals(pNode.getValue().toString(), n.getParentId().toString())) {
                childNodes.add(n);
            }
        }
        return childNodes;
    }

    /**
     * 判断是否为根节点
     */
    public boolean rootNode(Node node) {
        boolean isRootNode = true;
        for (Node n : nodes) {
            String parentId = Convert.toStr(node.getParentId(), "0");
            String value = Convert.toStr(n.getValue(), "0");
            if (StrUtil.equals(parentId, value)) {
                isRootNode = false;
                break;
            }


        }
        return isRootNode;
    }

    /**
     * 获取集合中所有的根节点
     */
    public List<Node> getRootNodes() {
        List<Node> rootNodes = new ArrayList<>();
        for (Node n : nodes) {
            if (rootNode(n)) {
                rootNodes.add(n);
            }
        }
        return rootNodes;
    }
}
